1 - introduksjon
R og python er to av de ledende programmeringsspråkene i dag. I motsetning til R er Python et "ordentlig" programmeringsspråk i den forstand at du kan skape objekter og klasser. R er et enklere språk med mindre muligheter når det gjelder programmering, men har til gjengjeld et langt større utvalg pakker innenfor statistikk og økonometri. For statistisk analyse er derfor R ofte foretrukket, men dersom du skal gjøre noe litt annet enn som tilbys i R-pakker, er det en fordel med et mer avansert programmeringsspråk som Python.
Python har mange fordeler. De viktigste er at det er:
Da de første datamaskinene kom på 40-tallet, måtte brukerne gi maskinene instruksjoner i form av maskinkode. Datamaskiner er binære og forstår kun to tegn; 1 og 0, det vil si "av" og "på". Brukeren måtte derfor forklare maskinen hva den skulle gjøre ved å skrive ned problemet som en lang rekke enere og nuller. Det ble raskt klart at dette var en ekstremt krevende oppgave. Programmeringsspråk ble derfor funnet opp for at mennesker skulle kunne gi instruksjoner til datamaskiner på en forståelig måte.
Stort sett alle programmeringsspråk henter syntaksen fra engelsk. Koden oversettes så til maskinspråk, noe som kalles å "kompilere" ("compile" på engelsk). Datamaskinen kan så behandle den kompilerte maskinkoden.
Programmeringsspråk deles inn i høynivå- og lavnivåspråk. Forskjellen på høy- og lavnivå er hvor mye støtte språket gir til brukeren. Slik støtte gjør det enklere å programmere, men er kostbart fordi det gir en mindre effektiv kode.
Lavnivåspråk er gir svært effektiv og rask kode, men er mer krevende og mindre intuitive å programmere. C++ er et lavnivåspråk. Eksemplet under skriver ut tallene 0 til og med 4:
for (int i = 0; i < 5; i++) {
std::cout << i << "\n";
}
Vi kan sammenligne dette med tilsvarende kode i Python, som er et høynivåspråk:
for i in range(5):
print(i)
Om du har åpnet denne filen i Jupyter notebook (se under for instruksjoner), kan du kjøre Pythonkoden ved å trykke SHIFT+ENTER.
Vi ser at Python-koden er langt enklere, og har en syntaks som ligner mer på vanlig engelsk. Generelt er Python et svært intuitivt språk som er enkelt å programmere i. Språket ble funnet opp av Guido van Rossum i 1989 og er i dag verdens mest populære programmeringsspråk rangert ut fra googlesøk.
Selv om Python er er et høynivåspråk, er det svært effektivt på grunn av et stort antall bibliotek hvor mye er skrevet direkte i C eller C++. Ett slik bibliotek heter "Numpy", og har svært effektive metoder for matriseoperasjoner. "Pandas" er et svært effektivt bibliotek for databehandling, og "Statsmodels" er et kraftfullt verktøy for dataanalyse.
Én ting som gjør det enklere å programmere i Python enn andre språk kan du allerede se av det lille eksemplet over. De fleste språk bruker ulike typer parenteser for å markere at noe tilhører en bestemt operasjon. Operasjonen over er en løkke, og vi ser fra Eksempel 21 at C bruker {} for å markere hva som er en del av løkken. I Python markeres tilhørighet til løkken med innrykk. Vi ser i Eksempel 1 at print(i)
tilhører løkken fordi denne setningen er rykket ett hakk inn.
Det har etterhvert etablert seg som god skikk og bruk innen programmering å ha et innrykk for kode som tilhører en operasjon. Vi ser det av Eksempel 1, der innholdet i løkken også er rykket inn. Forskjellen mellom C og Python er imidlertid at i C har hverken linjeskift eller innrykk noen som helst betydning for hvordan koden fungerer. Eksempel 1 kunne like gjerne vært skrevet på en linje som for (int i = 0; i < 5; i++) {std::cout << i << "\n";}
, og det ville fungert like bra.
I Python markeres imidlertid linjeskift et skille mellom setninger, og innrykk markere hva som tilhører hva. Det gir en kode som er enklere å lese og mer intuitiv.
For å lese dette dokumentet interaktivt må du åpne det i Jupyter. Jupyter gjør at du kan kjøre koden som ligger i dokumentene, og at du kan endre og skrive din egen kode. Undervisningen i dette kurset vil hovedsakelig gjøres i Jupyter. Før du kan kjøre dettei Jupyter, må du laste ned kursmateriellet fra Github.
Github er et av mange nettsteder som tilbyr "versjonskontroll" på git-platformen. Git er et åpen-kildekode-prosjekt som organiserer programmeringsprosjekt. I et typisk prosjekt er det flere personer som samarbeider og som kan endre koden. Git gjør det mulig å holde orden på hvem som endret hva når. Det gjør det også enkelt å gå tilbake til tidligere versjoner, og du kan "forke", eller "gafle" på norsk, som vil si å lage en ny gren med en annen kode en hovedgrenen.
Forelesningsnotatene for dette kurset er altså lagret i et "repositorie" på github.com, eller "repo" som det ofte kalles. Du kan se filene i nettleseren her: https://github.com/espensirnes/notebooks. Du kan laste dem direkte ned derfra, men det er mye bedre å bruke git-verktøyet til å laste dem ned. Da kan du kjøre kodene i notatboken interaktivt. I "0 - installasjon og tips.ipynb" finner du de mest brukte git-kommandoene
Det finnes flere ulike måter å kjøre Jupyter på. Det kan kjøres lokalt på PC'en eller på nettet. Det enklester er å kjøre jupyter fra din lokale maskin. I installasjonsveiledningen i kapittel 0 står det hvordan du
Når du har gjort dette, kan du starte jupyter lab med kommandoen
jupyter lab
Nå bør det ha åpnet seg et nettleservindu med forelesningsnotatene som filer i navigasjonsfeltet til høyre. Eventuelt må du klikke deg inn på notebook
-mappen. Du kan nå klikke på "1 - introduksjon.ipynb", og en interaktiv versjon av denne filen vil åpne seg.
(UiT har også en nettbasert løsning her)
Du bør nå ha åpnet denne Jupyter arbeidsboken i jupyter lab, slik at den er interaktiv. Du kan nå prøve å trykke i cellen under og kjøre koden ved å trykke SHIFT+ENTER. Om ikke teksten "Hello World!" dukker opp under, så, gå gjennom prosedyren over én gang til.
print('Hallo verden!')
Legg merke til funksjonen print()
. Den viser frem resultatet under cellen der den er brukt, og er en funksjon vi kommer til å bruke mye.
Den siste linjen vises alltid, så print
har virkning i Jupyter når den ikke står i siste setning. Forsøk å skrive to linjer med 'Hallo verden!' med og uten print
i forskjellige rekkefølger for å se dette. Det vil fra nå av forutsettes at du leser disse notatene interaktivt i Jupyter Lab eller Notebook.
print, i betydningen å skrive ut til skjermen, har vi forøvrig ikke noe godt norsk ord for, så dette vil heretter kalles for å printe.
Vi kommer i utstrakt grad til å bruke DataCamp i dette kurset. DataCamp er en plattform med nettleksjoner i programmering, med selvrettende øvelser. En del av pensum og obligatoriske øvelser i dette kurset vil hentes fra DataCamp.
Det finnes flere alternative måter å installere og jobbe med Python. Vi kommer som nevnt til å bruke Jupyter installert på lokal maskin, men senere i dette programmet vil det bli behov for andre verktøy enn Jupyter.
Den enkleste installasjonen er å kun installere selve Python-programmet direkte fra https://www.python.org/ og koden kjøres fra kommandolinje (bildet til høyre). Python startes med kommandoen "python". På mac må man ofte legge til versjonsnummeret, for eksempel "python38" for versjon 3.8. Dette gir en interaktiv økt der pythonkoden kjøres hver gang du trykker ENTER.
Å bruke en såkalt "IDE" gir imidlertid langt mer fleksibilitet. En IDE er et program som hjelper deg å lage og redigere python-filer. Dersom du skal lage et mer omfattende program i Python er det hensiktsmessig å lage filer. Hver fil er en modul som du kan kalle opp dersom du arbeider i samme mappe. Det går for eksempel an å samle noen funksjoner du bruker mye i en fil, og så importere denne filen når du skriver kode i Jupyter.
Det finnes flere ulike alternativer for IDE'er, men et godt og gratis alternativ er Visual Studio Code. VS Code støtter også flere andre programmeringsspråk. Men, som nevnt, detter er ikke noe du trenger til dette kurset.
Python, som de fleste andre programmeringsspråk, er basert på engelsk språk. Det er naturlig, siden engelsk er det overlegent største andrespråket i verden og de fleste programmeringsspråk har blitt utviklet i USA (her er Python et unntak). Av samme grunn bør all kode i utgangspunktet skriver på engelsk. Kode bør kunne deles globalt, og da bør den skrives på et språk flest mulig forstår.
Men selv om koden er engelsk, så er ofte brukergrensesnittet på lokalt språk. Du har kanskje norsk som språk i nettleseren din men bortsett fra navnene i menyene er all kode på engelsk.
I dette kurset skal vi gjøre det på tilsvarende måte. All kode skal i hovedsak skrives på engelsk. Printing kan imidlertid gjøres på norsk, slik som dette:
#let us make a simple program
my_sentence="Her er det lov å skrive norsk, for dette skal ut til skjermen!"
print(my_sentence)
Legg merke til den første setningen i programmet, #let us make a simple program
. Hash-tenget #
først, angir at denne linjen ikke skal oppfattes som en del av programmet. Pyhon overser dermed denne setningen. Denne funksjonen finnes, slik at vi kan dokumentere koden. Det vil si at vi skriver inn i koden hva som skjer.
Program blir ofte veldig fort veldig komplekse og uoversiktlige. Uten noen forklaring blir det fort vanskelig eller uoverkommelig for andre å forstå hva du har tenkt. Da blir det veldig vanskelig for andre å komme inn eller ta over prosjektet ditt. Det er også enklere for deg selv å gå tilbake og lese din egen kode, om du har vært flink å dokumentere den med kommentarer.
For å gjøre koden så godt leselig som mulig for andre, er det noen prinsipper som bør følges. Det er lite hensiktsmessig å gå detaljert inn på disse nå, før vi har lært litt mer, men vi tar med de generelle prinsippene som Tim Peters har laget, som du kan kikke tilbake på etterhvert som du lærer mer:
namespaces
er en fantastisk idé, -- la oss gjøre mer av det!Variablene i Python kan være ulike objekter som i alle andre programmeringsspråk, og typen objekt defineres av hva du setter variabelen til. Det er vanlig å definere stort sett alle variabler med små bokstaver i Python. Kun unntaksvis brukes store bokstaver.
Du kan ikke bruke mellomrom i variabelnavn. Det vil oppfattes som flere ulike navn. For eksempel er number_of_apples
tillatt men ikke "number of apples". Vi bruker også kun engelske bokstaver, selv om norske fungerer. aintail_æpla
kan altså brukes, men anbefales ikke.
bool
(Sann/Usann)¶Den enkleste variabelen i Python er den binære typen "bool". Den kan ta to verdier, True
eller False
(sant eller usant). Denne variabelen brukes mest i sammenhenger der vi skal teste om et vilkår er oppfylt eller ikke. Da bruker vi if
-setninger, som vi skal komme tilbake til.
Vi kan sjekke hvilken type en variabel er med funksjonen type(). Under får vi bekreftet apple_is_tasty
er en boolsk variabel.
#bool
apple_is_tasty=True
type(apple_is_tasty)
Legg merke til hva som skjer her: Første linje er bare en kommentar, som nevnt i forrige kapittel. I andre linjer setter vi variabelen apple_is_tasty
lik verdien True
. Det er på denne måten vi definerer variabler i Python. Når vi har satt en variable på denne måten, bestemmer det hvilken type
variabel det er.
Det er ikke alltid at variabelen settes rett før vi skal bruke den. Er det et stort program kan variabelen ha vært satt på en helt annen plass i programmet. I så fall er det nyttig å vise hvilken type variabel apple_is_tasty
representerer. Siden den er satt til verdien True
(sant), er det en bool
.
Når vi kjører et kodefelt i Jupyter, får vi resultatet av den siste setningen skrevet ut til skjermen, etter kodefeltet. Om du har kjørt koden, vil du se at det står bool
der. Det er fordi funksjonen type()
står i siste linje, og den returnerer hvilken type apple_is_tasty
er.
int
(heltall)¶int representerer hele tall i Python. Under ser vi at Python tolker 8 som et heltall:
# integer:
number_of_apples = 8
type(number_of_apples)
Vi kan konvertere int til bool og bool til int ved å bruke disse som funksjoner slik som dette:
type(int(apple_is_tasty))
type(bool(0))
Legger merke til at i python så tilsvarer 1 True
og 0 tilsvarer False
, slik at
20*False
20*True
float
(desimaltall)¶Regning gjøres vanligvis med desimaltall, eller "floating point" som det kalles av på fagspråket. I python heter derfor denne variabeltypen float
.
Om for eksempel 11 skal tolkes som et heltall, gir vi beskjed til Python om at det er et desimaltall ved å skrive det med én desimal. Alle programmeringsspråk, inkludert Python, bruker punktum som desimaltegn.
# floating point (float):
apple_price = 11.0
type(apple_price)
Navnet "floating point", eller flyttall på norsk, kommer av at alle flyttall har eksakt like mange siffer, men desimaltegnet kan flyttes slik at float
kan representere et svært stort spenn av verdier. Det største flyttallet er én med 308 nuller etter. Desimaltegnet flyttes enkelt fordi at float
egentlig er på "vitenskapelig form" (se under), selv om det ofte vises som vanlig tall. For eksempel så kan vi skrive tallet 102 på vitenskapelig form, men Python spytter det ut på et format vi enklere kan forstå
insane_apple_price = 1.02e+2
print(insane_apple_price)
Vitenskapelig form 1.02e+2
er en kombinasjon av et heltall (1
), desimaler (.02
) og hvilken potens av 10 tallet skal multipliseres med (e+2
).
1.02e+2
betyr altså at $1.02$ skal multipliseres med $10^{2}=100$.
1.02e+2
betyr dermed $1.02\cdot 10^{2}=102$. På samme kan $0.0102$ skrives 1.02e-2
, eller $1.02\cdot 10^{-2}=102$.
Legg også merke til at funksjonen print()
er brukt her. Det er ofte bedre å printe eksplisitt med printfunksjonen. Dersom det du ønsker å se ikke står sist i koden er det også nødvendig å bruke print()
.
Her er et eksemple med et lite flyttall:
really_cheap_apple_price = 1.02e-2
print(really_cheap_apple_price)
Når vi skriver ut resultatet får vi det altså ut som 102.0
eller 0.0102
i stedet for det vitenskapelige flyttallformatet. Det er fordi Python skjønner at 1.02e+2
og 1.02e-2
ikke ser så pent ut for oss. Python formaterer derfor tallet til et mer lesbart format før det skrives ut.
Det er enkelt å regne med både float
og int
:
total = apple_price*number_of_apples
print(total)
Heldigvis spiller det liten rolle om noe er int
eller float
når du skal regne. I de fleste andre programmeringsspråk får du et nytt heltall når du deleret heltall på et annet. I Python gir dette et desimaltall:
number_of_persons = 5
apple_per_person = number_of_apples/number_of_persons
print(apple_per_person)
float
¶For de fire regneartene fungerer float
slik vi har lært på barneskolen:
print(2+3)
print(2-3)
print(2*3)
print(2/3)
Ofte har vi imidlertid bruk for å opphøye et tall i et annet. Om vi for eksempel vil vite hva $2\cdot2\cdot2$ er, så kan vi istedet skrive $2^3$. Dette kalles en potens med 2 som grunntall og 3 som eksponent. I python utføres denne operasjonen med dobbelt gange-tegn **
. Dette er ulikt endel andre programmeringsspråk, der cirkumfleks-symbolet ^
ofte brukes.
Slik regner du med potens i Python:
2**3
str
(tekst)¶Tekst kalles "streng" på dataspråket, eller "string" på engelsk. Typen som representerer tekst heter derfor str
. Vi forteller Python at dette er en tekst ved å sette anførselstegn rundt. Her er et eksempel på en streng:
# string:
x="Dette er en streng (dvs tekst)"
type(x)
Det er enkelt å sette sammen string
og andre variabler i Python. Det er flere måter å gjøre det på, men vi skal bruke en metode som er ganske ny i Python. Fra og med versjon 3.6 kom noe som kalles "f-strings" som gir oss en veldig enkel måte å blandet tekst og andre variabler. Her er et eksempel:
print(f"Det er {apple_is_tasty} at jeg synes epler smaker godt.")
Legg merke til f'en før det første anførselstegnet. Den angir at dette er en f-streng og at alt som er inne i klammeparenteser {} skal omformateres til string
og tas med i teksten.
Et alternativ er å bruke +
-tegnet. Det går nemlig an å summere tekst i Python:
"Jeg "+"gikk "+"derfor "+"på "+"butikken "+"for "+"å "+"kjøpe"
Men det går ikke an å summere tekst og andre variabler, da skjønner ikke Python hva du ønsker å oppnå
"Jeg gikk derfor på butikken for å kjøpe " + number_of_apples + " epler. "
Du må i så fall omformatere tallet number_of_apples
til streng:
"Jeg gikk derfor på butikken for å kjøpe " + str(number_of_apples) + " epler."
Derfor er det langt enklere å bruke f-strings. Dersom tekststrengen er for lang for én linje, kan du sette flere tekstrenger etter hverandre på hver sin linje, slik som dette:
print(
f"Det er {apple_is_tasty} at jeg synes epler smaker godt. \n"
f"Jeg gikk derfor på butikken for å kjøpe {number_of_apples} epler. \n"
f"Innehaveren gav meg en vanvittig pris. Hun skulle ha {insane_apple_price} kroner per eple. \n"
f"Jeg fortalte henne at det var helt uaktuelt, og foreslo {really_cheap_apple_price} kroner. \n"
f"Hun avslo, men vi ble til sist enig om {apple_price} kroner.\n"
f"Jeg betalte hennet til sammen {apple_price*number_of_apples} kroner og dro hjem. \n\n"
f"På veien traff jeg {number_of_persons} venner. Jeg hadde ikke noe annet valg enn å dele eplene mine med dem. \n"
f"Det ble {number_of_apples/number_of_persons} epler per person.\n"
)
Merk at setningene må stå inne i en parentes, for eksempel som argument i en funksjon som over, for at Python skal forstå at de skal settes sammen til én setning. Legg også merke til \n
på slutten av hver delsetning. Denne indikerer at det skal være linjeskift etter hver delsetning.
Det finnes tre forskjellige typer tegn for å markere at noe er tekst i Python. Disse er apostrof '
, anførselstegn "
og trippel anførselstegn """
. Rollen til de to første typene er å enkelt kunne bruke anførselstegn inne i teksten:
print( "Jeg gikk derfor på butikken for å 'kjøpe' epler.")
print( 'Jeg gikk derfor på butikken for å "kjøpe" epler.')
Trippel anførselstegn """
brukes når du vil ha tekst over flere linjer, for eksempel
s=f"""Det er {apple_is_tasty} at jeg synes epler smaker godt.
Jeg gikk derfor på butikken for å kjøpe {number_of_apples} epler.
Innehaveren gav meg en vanvittig pris. Hun skulle ha {insane_apple_price} kroner per eple.
Jeg fortalte henne at det var helt uaktuelt, og foreslo {really_cheap_apple_price} kroner.
Hun avslo, men vi ble til sist enige om {apple_price} kroner.
Jeg betalte hennet til sammen {apple_price*number_of_apples} kroner og dro hjem.
På veien traff jeg {number_of_persons} venner. Jeg hadde ikke noe annet valg enn å dele eplene mine med dem.
Det ble {number_of_apples/number_of_persons} epler per person."""
print(s)
Alternativt kan du sette hver setning på linje etterhverandre med egne enkel anførselstegn, som i Eksempel 21, men da må alle setningene befinne seg inne i en parentes.
Bruk koden i Eksempel 19, men fjern \n
og se hva som skjer
Lag variabler som du putter inn i en historie som i Eksempel 21
a) Hvilke variabler kan brukes sammen med multiplikasjonsoperatoren *
?
prøv for eksempel "hei"*2.0
og True*2.0
b) Hvilke variabler kan brukes sammen med addisjonsoperatoren +
?
c) Hvilke variabler kan brukes sammen med divisjonsoperatoren /
?
e) Hvilke variabler kan brukes sammen med subtraksjonsoperatoren -
?
a) Forsøk med prøving og feiling å finne det størst mulige float
-tallet som ikke blir inf
b) Forsøk med prøving og feiling å finne float
-tallet nærmest null som ikke blir 0.0
1) Hva er hensikten med en boolsk variabel i Python?
2) Hvordan kan du konvertere
1) en boolsk verdi til en heltall verdi i Python?
2) et heltall til en streng i Python?
3) et flyttall til et heltall i Python?
3) Hvorfor bruker vi f-strings i Python, og hvordan bruker du dem for å kombinere tekst og variabler?
4) Hvordan representerer du desimaltall i Python, og hva er spesielt med hvordan de lagres i minnet?
5) Hva betyr det å heve et tall til en potens, og hvordan utfører du denne operasjonen i Python?
x
og y
først. Koden skal viser summen, differansen, produktet, forholdet og x
i potens av y
.
var_type
og x
. Du skal sette var_type
til en datatype og x
til en verdi, for eksempel slik som under. Koden skal konvertere x
til datatypen angitt av var_type
, og printe ut type og verdi før og etter konverering. Forsøkt så med ulike verdier for x
og ulike datatyper i var_type
. var_type=int
x = 2.2